#include "pm.h"
#include "ui_pm.h"

extern QSqlDatabase ManagementDB;
extern QSqlDatabase projectDB;
extern QStringList oneProjectInfo;

PM::PM(QDialog *parent) :
    QDialog(parent),
    ui(new Ui::PM)
{
    ui->setupUi(this);
    
    //Create ManagementDBOP
    if(!connectManagementDB(MANAGEMENTDB_NAME))
    {
        exit(CONNECT_MANAGEMENTDB_FAILED);
    }
    if(!initManagementDB())
    {
        exit(INIT_MANAGEMENTDB_FAILED);
    }
    
    error = new ErrorToDo;
    
    // Create and set the data model
    model = new QSqlQueryModel;
    model->setQuery(QString("select * from %1").arg(PM_TABLE_NAME), ManagementDB);
    model->setHeaderData(1, Qt::Horizontal, "名称");
    model->setHeaderData(2, Qt::Horizontal, "创建时间");
    model->setHeaderData(3, Qt::Horizontal, "最后更改时间");
    model->setHeaderData(4, Qt::Horizontal, "是否是正在使用的项目");
    
    //Show data use tableView and set tableView
    ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);  //设置选中时选中一行
    ui->tableView->setModel(model);
    ui->tableView->hideColumn(0);  //隐藏id列(第0列)
    ui->tableView->resizeColumnsToContents();
    ui->tableView->verticalHeader()->hide();
    ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);//均分列
//    ui->tableView->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);//均分行
    
    //Create action
    actionOpenPro = new QAction("打开", this);
    actionDelPro = new QAction("删除", this);
    actionExportPro = new QAction("导出", this);
    actionUpdateProName = new QAction("更改项目名称", this);
    
    //Connect signals and Slots
    connect(ui->createProBtn, SIGNAL(clicked(bool)), this, SLOT(createPro()));
    connect(ui->importProBtn, SIGNAL(clicked(bool)), this, SLOT(importPro()));
    connect(actionDelPro, SIGNAL(triggered(bool)), this, SLOT(deletePro()));
    connect(actionOpenPro, SIGNAL(triggered(bool)), this, SLOT(openPro()));
    connect(actionExportPro, SIGNAL(triggered(bool)), this, SLOT(exportPro()));
    connect(actionUpdateProName, SIGNAL(triggered(bool)), this, SLOT(updateProName()));
    connect(ui->tableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(openPro()));
    connect(actionOpenPro, SIGNAL(triggered(bool)), this, SLOT(accept()));
    connect(ui->tableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(accept()));
}

PM::~PM()
{
    delete error;
    ManagementDB.close();
    delete ui;
}

void PM::on_tableView_customContextMenuRequested(const QPoint &pos)
{
    rightMousePos = pos;
    setMouseRightClickMenu();
}

void PM::updateTableView()
{
    model->setQuery(QString("select * from %1").arg(PM_TABLE_NAME), ManagementDB);
    ui->tableView->resizeColumnsToContents();
}

bool PM::setMouseRightClickMenu()
{
    //判断鼠标位置
    int column = ui->tableView->indexAt(rightMousePos).column();
    if(column < 0)
        return false;
    
    QMenu *popMenu = new QMenu(this);
    
    popMenu->addAction(actionOpenPro);
    popMenu->addAction(actionDelPro);
    popMenu->addAction(actionExportPro);
    popMenu->addAction(actionUpdateProName);
    
    popMenu->exec(QCursor::pos());
    
    return true;
}

void PM::addProjectToDB(QString proName)
{
    QDateTime CurrentTime = QDateTime::currentDateTime();
    QString Timestr = CurrentTime.toString("yyyy-MM-dd hh:mm:ss");
    int id = selectNextProjectID();
    
    if(insertProject(id, proName, Timestr, Timestr))
    {
        if(selectOneProjectInfo(id))
        {
            QString proFilePath = QString(DB_PATH).append(oneProjectInfo.at(0)).append(SUFFIX);
            qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"最终新建项目数据库名:"<<proFilePath;
            if(connectProjectDB(proFilePath))
            {
                initProjectDB();
                updateTableView();
            }
            projectDB.close();
        }
    }
    else
        qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"添加项目到项目管理数据库失败";
}

void PM::createPro()
{
    createProDialog *createProDlg = new createProDialog;
    
    createProDlg->show();
    if(createProDlg->exec() == QDialog::Accepted)
    {
        addProjectToDB(createProDlg->createProName);
    }
}

void PM::deletePro()
{
    int row = ui->tableView->currentIndex().row();  //获取当前行
    QModelIndex index = model->index(row, 0);  //获取当前行的第零列(存项目id，隐藏列)
    QVariant data = model->data(index);
    int projectID = data.toInt();
    QString projectFileName= QString(DB_PATH).append(model->data(model->index(row, 1)).toString()).append(SUFFIX);
    
    qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"projectName,projectID:"<<projectFileName<<projectID;
    
    QFile file(projectFileName);
    if(file.exists())
    {
        QDir dir;
        qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"找到要删除的文件，此时位置："<<dir.currentPath();
        if(!file.remove())
        {
            qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"删除项目文件失败";
            error->showCriticalMsg(this, "删除项目文件失败");
            return;
        }
    }
    else
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"要删除的项目文件不存在";
        error->showCriticalMsg(this, "要删除的项目文件不存在");
        return;
    }
    
    if(!deleteProject(projectID))
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"删除项目失败";
        error->showCriticalMsg(this, "删除项目失败");
        return;
    }
    
    updateTableView();
}

void PM::openPro()
{
    int row = ui->tableView->currentIndex().row();  //获取当前行
    QModelIndex index = model->index(row, 0);  //获取当前行的第零列(存项目id，隐藏列)
    QVariant data = model->data(index);
    int projectID = data.toInt();
    
    if(!updateProjectFlagByID(projectID, USEING_FLAG))
    {
        qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"更新flag失败";
        error->showCriticalMsg(this, "更新flag失败");
    }
    ManagementDB.close();
}

void PM::importPro()
{
    QFileDialog *fileDialog = new QFileDialog(this);
    fileDialog->setWindowTitle(tr("导入项目文件"));
    fileDialog->setDirectory(".");
    //设置文件过滤器
    fileDialog->setNameFilter(QString("项目文件(*%1)").arg(SUFFIX));
    fileDialog->setViewMode(QFileDialog::Detail);
    
    //打印所选择的文件名
    QStringList filePathNames;
    QString fileName;
    if(!fileDialog->exec())
        return;
    QFileInfo fi;
    filePathNames = fileDialog->selectedFiles();
    fi = QFileInfo(filePathNames.at(0));
    fileName = fi.fileName();
    qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<fileName;
    
    //目前的做法是将导入的项目文件拷贝到项目存放文件夹下
    QString destFile = QString(DB_PATH).append(fileName);
    copyFileToPath(filePathNames.at(0), destFile, 0);
    
    //添加到数据库
    addProjectToDB(fileName.remove(SUFFIX));  //注意去掉后缀和“.”
}

void PM::exportPro()
{
    int row = ui->tableView->currentIndex().row();  //获取当前行
    QModelIndex index = model->index(row, 1);  //获取当前行的第1列
    QVariant data = model->data(index);
    QString projectName = QString(DB_PATH).append(data.toString()).append(SUFFIX);
    qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<projectName;
    
    QString fileName;
    fileName = QFileDialog::getSaveFileName(this,
    tr("导出项目文件"), "", QString("项目文件 (*%1)").arg(SUFFIX));
    
    if (!fileName.isNull())
    {
        qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<fileName;
        copyFileToPath(projectName, fileName, 0);
    }
}

void PM::updateProName()
{
    updateProNameDlg *dlg = new updateProNameDlg;
    
    dlg->show();
    if(dlg->exec() == QDialog::Accepted)
    {
        int row = ui->tableView->currentIndex().row();  //获取当前行
        QModelIndex index = model->index(row, 0);  //获取当前行的第零列(存项目id，隐藏列)
        QVariant data = model->data(index);
        int projectID = data.toInt();
        
        qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"新项目名："<<dlg->proName;
        updateProjectName(projectID, dlg->proName);
        updateTableView();
    }
}

bool PM::copyFileToPath(QString sourceDir ,QString toDir, bool coverFileIfExist)
{
	toDir.replace("\\","/");
	if(sourceDir == toDir){
		return true;
	}
	if(!QFile::exists(sourceDir)){
		return false;
	}
	QDir *createfile     = new QDir;
	bool exist = createfile->exists(toDir);
	if (exist){
		if(coverFileIfExist){
			createfile->remove(toDir);
		}
	}
 
	if(!QFile::copy(sourceDir, toDir))
	{
		return false;
	}
	return true;
}
